
import java.awt.*;
import javax.swing.Timer;
import java.awt.geom.*;
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.FileNotFoundException;
import java.io.IOException; 
import java.util.ArrayList;
import java.util.Scanner;
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 
import javax.swing.JPanel; 
import java.applet.*;
import java.awt.Color;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.Timer;
import javax.swing.Action;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Main extends Applet implements KeyListener {
	
	private Thing map[][];
	
	private AbstractFactory factory;
	
	private int timeout = 2;

	private ArrayList<Monster> monsterList = new ArrayList<Monster>();	  
	
	private boolean firstRun = true;
	
	/**
	 * frame init
	 */
	public void init() {
        super.init();
        final Graphics g = getGraphics();
        setBackground(Color.white);
        this.addKeyListener(this);
        Scanner mazeScanner;
		try {
			mazeScanner = new Scanner(new File("D:/maze.txt"));
			
			int dimensionX = mazeScanner.nextInt();
			int dimensionY = mazeScanner.nextInt();
			map = new Thing[dimensionX][dimensionY];
			for (int i = 0; i < dimensionX; i ++) {
				for (int j = 0; j < dimensionY; j ++) {
					boolean isMonster = false;
					boolean isWallOrBonus = false;
					int a = mazeScanner.nextInt();
					switch (a) {
					case 1:
						factory = new WallFactory();
						isWallOrBonus = true;
						break;
					case 4: 
		            	//factory = new RandomStrategyFactory();
						//factory = new SmartStrategyFactory();
						factory = new RandomStrategyWithEyesFactory();
		            	isMonster = true;
		            	break;
					}
					if (isMonster) {
					monsterList.add((Monster)factory.create(i, j)); };
					if (isWallOrBonus){
						map[i][j] = factory.create(i, j);
						
					}
				}
			}
			
        } catch (FileNotFoundException e) {
			e.printStackTrace();
		}
        Nothing n = new Nothing();
        for (int i = 0;i<map.length;i++)
		{
			for (int j = 0;j<map.length;j++)
			{
				if(map[i][j]==null) map[i][j] = n;
			}
		} 
        p1 = new Pacman(0, 0, map);
        
        for (Monster currentMonster: monsterList) {
        	currentMonster.init(map, p1);
        }
       
        Timer t1 = new Timer(200, new ActionListener() {
        	public void actionPerformed(ActionEvent event) {
        		for (Monster currentMonster: monsterList) {
        			if (currentMonster.ifFail(p1.getX(), p1.getY()))
                    	System.exit(0);
            	}
        		p1.actionPerformed(event);
                paint(getGraphics());
                timeout++;
           	}
        });
            
        t1.start();
    }
	
	private boolean b = false;
	
	private Pacman p1;
	
	private static final long serialVersionUID = 4902057285471885308L;
    
	/**
	 * drawing method
	 */
	public void paint(final Graphics g) {
       	if (firstRun) {
       		for (int i = 0; i < map.length; i ++) {
       		   for  (int j = 0; j < map[0].length; j ++) {
   					if (map[i][j] != null) {
   						map[i][j].draw(getGraphics());
   					}
       		   }
       		}
       		firstRun = false;
       	}
    	
    	p1.draw(g);
    	if (timeout == 2) {
    		timeout = 0;
    		for (Monster currentMonster: monsterList) {
    			currentMonster.draw(g);
    		}
       	}        
        //super.paint(g);
    }
	
	public void keyPressed(KeyEvent arg0) {
		
		
	}
	
	public void keyReleased(KeyEvent arg0) {
		
		p1.keyReleased(arg0);
	}
	
	public void keyTyped(KeyEvent arg0) {
		
		
	}   
}
